<?php

namespace baofu;


use baofu\SecurityUtil\AESUtil;
use baofu\SecurityUtil\RSAUtil;
use baofu\SecurityUtil\SignatureUtils;
use baofu\SecurityUtil\SHA1Util;
use baofu\Util\Log;
use baofu\Util\HttpClient;
use baofu\Util\Tools;
use think\Exception;

/**
 * 退款类接口
 * @package baofu
 *
 *
 */
class Refund
{

    public $Version = "4.0.0.0";//版本号
    public $Member_Id = "100029078";    //商户号
    public $Terminal_Id = "200004282";    //终端号

    public $KEY_PWD = "123456";    //商户私钥证书密码

    public $KeyFolder = EXTEND_PATH . '/baofu/CerFile/';    //证书路径
    public $PFX_FILE_PATH = "bfkey_100029078@@200004282.pfx";  //注意证书路径是否存在
    public $CER_FILE_PATH = "bfkey_100029078@@200004282.cer";//注意证书路径是否存在

    public $POST_URL = "https://vgw.baofoo.com/cutpayment/protocol/backTransRequest";  //测试环境请求地址

    //https://vgw.baofoo.com/cutpayment/api/backTransRequest
    public $AesKey = '4f66405c4f66405c'; //商户自定义（可随机生成  商户自定义(AES key长度为=16位)）

    public $GLOBALS = [];

    public function __construct($config = [])
    {
        $this->PFX_FILE_PATH = $this->KeyFolder . $this->PFX_FILE_PATH;
        $this->CER_FILE_PATH = $this->KeyFolder . $this->CER_FILE_PATH;

        if(!empty($config)){
            $this->Version = $config['baofu_tui_version'];
            $this->Member_Id = $config['baofu_tui_member_Id'];
            $this->Terminal_Id = $config['baofu_tui_terminal_Id'];
            $this->KEY_PWD = $config['baofu_tui_key_pwd'];
            $this->PFX_FILE_PATH = ROOT_PATH.'/public/'.$config['baofu_tui_pfx'];
            $this->CER_FILE_PATH = ROOT_PATH.'/public/'.$config['baofu_tui_cer'];
            $this->POST_URL = $config['baofu_tui_url'];
            $this->AesKey = $config['baofu_tui_AesKey'];
        }

        $this->GLOBALS = [
            'Version' => $this->Version,
            'Member_Id' => $this->Member_Id,
            'Terminal_Id' => $this->Terminal_Id,
            'KEY_PWD' => $this->KEY_PWD,
            'PFX_FILE_PATH' => $this->PFX_FILE_PATH,
            'CER_FILE_PATH' => $this->CER_FILE_PATH,
            'POST_URL' => $this->POST_URL,
        ];
    }

    public function dgtl_envlp(){
        try {
            Log::LogWirte('dgtl_envlp-开始');//记录日志
            $dgtl_envlp = "01|" . $this->AesKey;//使用接收方的公钥加密后的对称密钥，并做Base64转码，明文01|对称密钥，01代表AES[密码商户自定义]
            Log::LogWirte('dgtl_envlp-'.$dgtl_envlp);//记录日志
            Log::LogWirte('dgtl_envlp-'.$this->GLOBALS["CER_FILE_PATH"]);//记录日志
            return RSAUtil::encryptByCERFile($dgtl_envlp, $this->GLOBALS["CER_FILE_PATH"]);//公钥加密
        }catch (Exception $exception){
            Log::LogWirte('error-'.$exception->getMessage());//记录日志
        }
    }

    public function getDateAry($arr = []){
        $DateArry = array();
        $DateArry['msg_id'] = $this->getMsgID();
        $DateArry["send_time"] = Tools::getTime();
        $DateArry["version"] = $this->GLOBALS["Version"];
        $DateArry["terminal_id"] = $this->GLOBALS["Terminal_Id"];
        $DateArry["member_id"] = $this->GLOBALS["Member_Id"];
        $DateArry['msg_id'] = $this->getMsgID();
        return $DateArry;
    }

    public function getMsgID(){
        return "TISN" . Tools::getTransid() . Tools::getRand4();
    }

    //商户订单号
    public function getTransID(){
        return "TID" . Tools::getTransid() . Tools::getRand4();
    }

    //退款流水号
    public function getTransSerialNo(){
        return "RTSN" . Tools::getTransid() . Tools::getRand4();
    }

    public function getDateArry(){

        $dgtl_envlp = $this->dgtl_envlp();

        $DateArry = array();
        $DateArry["send_time"] = Tools::getTime();
        $DateArry["msg_id"] = "TISN" . Tools::getTransid() . Tools::getRand4();//报文流水号
        $DateArry["version"] = $this->GLOBALS["Version"];
        $DateArry["terminal_id"] = $this->GLOBALS["Terminal_Id"];
        $DateArry["member_id"] = $this->GLOBALS["Member_Id"];
        $DateArry["dgtl_envlp"] = $dgtl_envlp;

        return $DateArry;
    }

    /**
     * 订单退款
     * @param $trans_id 原订单号
     * @param $refund_amt 退款金额,分
     * @return mixed|void
     * @throws \think\Exception
     */
    public function action($trans_id = '',$refund_amt = 0,$trans_serial_no = ''){

        Log::LogWirte('开始退款');//记录日志
        \think\Log::write('开始退款');

        $ArrayData = [
            "version" => $this->GLOBALS["Version"],//请求参数（明文参数）  1
            "txn_sub_type"=> "09",  //1
            "member_id" =>$this->GLOBALS["Member_Id"],  //1
            "terminal_id" => $this->GLOBALS["Terminal_Id"], //1
            "trans_serial_no"=> "RTSN".Tools::getTransid().Tools::getRand4(),//退款流水号(每次请求不重复) 1
            "additional_info"=> "附加信息", //1
            "req_reserved"=> "保留",  //1
        ];

        $ArrayData["trans_id"]= $trans_id;  //1
        $ArrayData["refund_order_no"]= $trans_serial_no;//退款时商户端生成的订单号(每次请求不重复) 1
        $ArrayData["refund_reason"]= "退款原因";    //1
        $ArrayData["refund_amt"]= $refund_amt;//退款金额 1
        $ArrayData["refund_time"]= Tools::getTime("YmdHis");//退款发起时间 1
        $ArrayData["notice_url"]= "";//退款成功后通知地址。 1
        $ArrayData["refund_type"]= '8';//1:网银、2:认证支付 1


        $Encrypted_string = str_replace("\\/", "/",json_encode($ArrayData));//转JSON


        $ApiPostData = [
            "version" => $this->GLOBALS["Version"],
            "member_id" => $this->GLOBALS["Member_Id"],
            "terminal_id" => $this->GLOBALS["Terminal_Id"],
            "txn_type" => '331',
            "data_type" => 'json',
            "txn_sub_type" => '09',
        ];
        $Encrypted = RSAUtil::encryptByPFXFile($Encrypted_string, $this->GLOBALS["PFX_FILE_PATH"], $this->GLOBALS["KEY_PWD"]);//先BASE64进行编码再RSA加密
        $ApiPostData["data_content"]=$Encrypted;

        $Result_Str = $this->Post($ApiPostData, $this->GLOBALS["POST_URL"]);//发送请求并接收结果

        $Result_DeStr = RSAUtil::decryptByCERFile($Result_Str, $this->GLOBALS["CER_FILE_PATH"]);

        Log::LogWirte('开始退款-返回-'.$Result_DeStr);//记录日志
        \think\Log::write('开始退款-返回-'.$Result_DeStr);

        if(!empty($Result_DeStr)){//解析返回参数。
            $endata_content = json_decode($Result_DeStr,TRUE);

            //需查询状态
            $resp_code = ['BF00100','BF00112','BF00113','BF00115','BF00307','BF00384','BF00203'];

            if($endata_content['resp_code'] == '0000'){

                return ['code' => 200,'notify' => $endata_content];

            }elseif(in_array($endata_content['resp_code'],$resp_code)){

                return ['code' => 201,'notify' => $endata_content];

            }else{

                return ['code' => 0,'notify' => $endata_content];
            }
        }
        return ['code' => 0,'notify' => $Result_DeStr];
    }

    /**
     * 查询退款
     * @param $refund_order_no 退款单号
     * @return mixed|void
     * @throws \think\Exception
     */
    public function queryAction($refund_order_no){
        $ArrayData = array(
            "txn_sub_type"=> "10",
            "member_id"=> $this->GLOBALS["Member_Id"],
            "terminal_id"=> $this->GLOBALS["Terminal_Id"],
            "trans_serial_no"=> "RTSN".Tools::getTransid().Tools::getRand4(),//退款流水号(每次请求不重复)
            "additional_info"=> "附加信息",
            "req_reserved"=> "保留",
            "data_type" => "json"
        );

        $Refund_ID = $refund_order_no;//退款商户订单号
        $ArrayData["refund_order_no"]= $Refund_ID;//商户退款时生成的订单号


        $Encrypted_string = str_replace("\\/", "/",json_encode($ArrayData));//转JSON


        $Encrypted = RSAUtil::encryptByPFXFile($Encrypted_string, $this->GLOBALS["PFX_FILE_PATH"], $this->GLOBALS["KEY_PWD"]);//先BASE64进行编码再RSA加密
        $ApiPostData["data_content"]=$Encrypted;


        $Result_Str = $this->Post($ApiPostData, $this->GLOBALS["POST_URL"]);//发送请求并接收结果
        $Result_DeStr = RSAUtil::decryptByCERFile($Result_Str, $this->GLOBALS["CER_FILE_PATH"]);

        if(!empty($Result_DeStr)){//解析返回参数。
            $endata_content = json_decode($Result_DeStr,TRUE);
            return $endata_content;
        }
    }

    public function Post($PostArry,$Req_Url){
        try {
            $postData = $PostArry;
            $postDataString = http_build_query($postData);//格式化参数
            Log::LogWirte('发送参数-'.$postDataString);//记录日志
            //Log::EchoFormat("发送参数：".$Req_Url."?".$postDataString);
            $curl = curl_init(); // 启动一个CURL会话
            curl_setopt($curl, CURLOPT_URL, $Req_Url); // 要访问的地址
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); // 对认证证书来源的检查
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); // 从证书中检查SSL加密算法是否存在
            //curl_setopt($curl, CURLOPT_SSLVERSION, 6); //CURL_SSLVERSION_DEFAULT (0), CURL_SSLVERSION_TLSv1 (1), CURL_SSLVERSION_SSLv2 (2), CURL_SSLVERSION_SSLv3 (3), CURL_SSLVERSION_TLSv1_0 (4), CURL_SSLVERSION_TLSv1_1 (5)， CURL_SSLVERSION_TLSv1_2 (6) 中的其中一个。
            curl_setopt($curl, CURLOPT_POST, true); //发送一个常规的Post请求
            curl_setopt($curl, CURLOPT_POSTFIELDS, $postDataString); // Post提交的数据包
            curl_setopt($curl, CURLOPT_TIMEOUT, 60); // 设置超时限制防止死循环返回
            curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);
            $tmpInfo = curl_exec($curl); // 执行操作
            if (curl_errno($curl)) {
                $tmpInfo = curl_error($curl);//捕抓异常
            }
            curl_close($curl); // 关闭CURL会话
            Log::LogWirte('返回参数-'.$tmpInfo);//记录日志
            return $tmpInfo; // 返回数据
        } catch (Exception $ex) {
            echo $ex->getTraceAsString();
        }
    }
}